package com.l.web.master.system.menu;

import org.bson.types.ObjectId;
import org.l.qiao.Cluster;
import org.l.qiao.search.Field;
import org.l.qiao.search.Query;
import org.l.qiao.search.Sort;
import org.l.qiao.search.Update;
import org.l.qiao.web.KeyUpdate;
import org.l.qiao.web.ResponseCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class MenuService {

    @Autowired
    private MenuDAO menuDAO;

    public List getList(Cluster sort) {
        List menus = menuDAO.find(null, null, sort);
        return menus;
    }

    public Cluster detail(String id, Map modelMap) {
        Cluster menu = menuDAO.findById(id);
        return menu;
    }

    public int save(Menu menu) {
        String parentid = menu.getString(Menu.PARENT_ID, "");
        List parent;

        if (parentid == null || "".equals(parentid)) {
            parent = new ArrayList();
            menu.remove(Menu.PARENT_ID);
        } else {
            Cluster cluster = menuDAO.findById(parentid);

            if (cluster.isEmpty()) {
                return ResponseCode.EXIST_NOT;
            }

            parent = cluster.getList(Menu.PARENT, new ArrayList());
            parent.add(cluster.get(Menu.ID));
            menu.put(Menu.PARENT_ID, cluster.get(Menu.ID));
        }

        String id = menu.setId();
        menu.put(Menu.PARENT, parent);
        menu.put(Menu.DEEP, parent.size());
        menu.put(Menu.CREATED, new Date());
        menuDAO.insert(menu);
        return ResponseCode.FINISH;
    }

    public List findParents(Cluster menu) {
        Query query = new Query();
        query.in(Menu.ID, menu.getList(Menu.PARENT, new ArrayList()));
        Field field = new Field(Menu.NAME);
        Sort sort = new Sort();
        sort.asc(Menu.DEEP);
        List parents = menuDAO.find(query, field, sort);
        return parents;
    }

    public int update(KeyUpdate keyUpdate) throws Exception {
        int result = ResponseCode.FINISH;

        if ("PARENT_ID".equals(keyUpdate.getName())) {
            result = updateParent(keyUpdate);
        } else {
            menuDAO.update(keyUpdate);
        }

        return result;
    }

    private int updateParent(KeyUpdate keyUpdate) {
        Cluster menu = menuDAO.findById(keyUpdate.getId());
        String parentId = keyUpdate.getValue();
        List oldParentList = menu.getList(Menu.PARENT, new ArrayList());
        List newParentList;

        if (parentId == null || "".equals(parentId)) {
            newParentList = new ArrayList();
            menu.remove(Menu.PARENT_ID);
        } else {
            Cluster parent = menuDAO.findById(parentId);
            if (parent.isEmpty()) {
                return ResponseCode.EXIST_NOT;
            }
            newParentList = parent.getList(Menu.PARENT, new ArrayList());
            newParentList.add(parent.get(Menu.ID));
            menu.put(Menu.PARENT_ID, parent.get(Menu.ID));
        }

        menu.put(Menu.PARENT, newParentList);
        menuDAO.save(menu);
        updateChildren(menu, oldParentList, newParentList);
        return ResponseCode.FINISH;
    }

    private void updateChildren(Cluster menu, List oldParentList, List newParentList) {
        Query query = new Query();
        query.eq(Menu.PARENT, menu.get(Menu.ID));
        Update update = new Update();
        update.pullAll(Menu.PARENT, oldParentList);
        update.push(Menu.PARENT, newParentList, null, 0);
        menuDAO.update(query, update, false, true);
    }

    public List parent(String id) {
        ObjectId objectId = new ObjectId(id);
        Query query = new Query();
        query.ne(Menu.PARENT, objectId);
        query.ne(Menu.ID, objectId);
        Field field = new Field();
        field.include(Menu.ID, Menu.NAME, Menu.PARENT_ID);
        List menus = menuDAO.find(query, field, null);
        return menus;
    }

    public int remove(List<String> ids) {
        Query query = new Query();
        query.idIn(ids);
        menuDAO.remove(query);
        return ResponseCode.FINISH;
    }

}
